package cn.school.workflow.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.school.common.utils.SysUserUtils;
import cn.school.workflow.dao.LeaveApplyDao;
import cn.school.workflow.service.LeaveApplyService;
import cn.school.workflow.service.WorkFlowCommonService;
import cn.school.workflow.vo.LeaveApplyVO;
import cn.school.workflow.vo.WorkFlowVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
public class LeaveApplyServiceImpl extends ServiceImpl<LeaveApplyDao, LeaveApplyVO> implements LeaveApplyService {

    @Autowired
    private WorkFlowCommonService workFlowCommonService;


    @Override
    public IPage<LeaveApplyVO> findLeaveApplyPageList(LeaveApplyVO vo) {
        LambdaQueryWrapper<LeaveApplyVO> wrapper = new LambdaQueryWrapper<>();
        if(!SysUserUtils.getSysUser().getDeptName().startsWith("人事")){
            //默认查询自己提交的申请
            wrapper.eq(LeaveApplyVO::getCreateBy,SysUserUtils.getSysUser().getUsername());
        }
        //添加租户条件
        wrapper.eq(LeaveApplyVO::getTenantId,vo.getTenantId());

        if(!StringUtils.isEmpty(vo.getApplyNo())){
            wrapper.eq(LeaveApplyVO::getApplyNo,vo.getApplyNo());
        }
        if(!StringUtils.isEmpty(vo.getLeaveType())){
            wrapper.eq(LeaveApplyVO::getLeaveType,vo.getLeaveType());
        }
        if(!StringUtils.isEmpty(vo.getTimes())){
            wrapper.le(LeaveApplyVO::getLeaveStartTime,vo.getTimes()).ge(LeaveApplyVO::getLeaveEndTime,vo.getTimes());
        }
        wrapper.orderByDesc(LeaveApplyVO::getCreateTime);
        return page(new Page<>(vo.getPageNum(), vo.getPageSize()), wrapper);
    }

    @Override
    public boolean cancelLeaveApply(WorkFlowVO vo) {
        LambdaQueryWrapper<LeaveApplyVO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LeaveApplyVO::getProcessId,vo.getProcessInstanceId());
        LeaveApplyVO applyVO = new LeaveApplyVO();
        applyVO.setStatus("4");//撤销流程
        applyVO.setModifyBy(SysUserUtils.getSysUser().getUsername());
        applyVO.setModifyTime(new Date());
        this.baseMapper.update(applyVO,wrapper);
        return workFlowCommonService.cancelApply(vo.getProcessInstanceId(),vo.getApplyDesc());
    }

    @Override
    public int createLeaveApply(LeaveApplyVO vo) {
        String username = SysUserUtils.getSysUser().getUsername();
        ///查询下级处理人
        List<String> approvalUser = getApprovalUser(vo);
        String applyNo = DateUtil.format(new Date(),"yyyyMMddHHmmssSSS");
        vo.setApplyNo("LE"+applyNo);
        vo.setCreateBy(username);
        vo.setCreateTime(new Date());
        String approvalSign = "";
        if(approvalUser.size()>0){
            //有多个审批人，只取第一个人来审批
            approvalSign = approvalUser.get(0);
        }
        vo.setCurrApprovedBy(approvalSign);
        //创建申请单
        this.baseMapper.insert(vo);

        WorkFlowVO flowVO = new WorkFlowVO();
        flowVO.setApplyTitle("请假申请");
        flowVO.setApplyID("leaveApply");
        flowVO.setBusinessKey(applyNo);
        //查询下级处理人
        Map<String,Object> map =new HashMap<>();
        map.put("assigneeList",approvalUser);
        flowVO.setVariables(map);
        //创建请假工作流
        String processInstanceId = workFlowCommonService.createProcessInstance(flowVO);
        vo.setProcessId(processInstanceId);
        //更新流程实例ID
        return this.baseMapper.updateById(vo);
    }

    /**
     * 获取选择部门的审批人
     * @param vo
     * @return
     */
    private List<String> getApprovalUser(LeaveApplyVO vo) {
        String deptStr = vo.getApprovedDept();
        String[] deptLevelItem = deptStr.split(";");
        List<Long> deptList= new ArrayList<>();
        for (String str:deptLevelItem){
            String [] deptIds = str.split(",");
            deptList.add(Long.valueOf(deptIds[deptIds.length-1]));
        }
        List<String> approvalUser = workFlowCommonService.findAssigneeList(deptList);
        return approvalUser;
    }

    @Override
    public LeaveApplyVO findLeaveApplyDetail(Long processInstanceId) {
        LambdaQueryWrapper<LeaveApplyVO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LeaveApplyVO::getProcessId,processInstanceId);
        return this.baseMapper.selectOne(wrapper);
    }

    @Override
    public Map<String, List<Object>> leaveApplyLastOneMonthGroup() {
        List<Map> list = this.baseMapper.getListByLastOneMonth();
        Map<String, Integer> dbResultMap = new HashMap<>();
        if (list != null && list.size() != 0) {
            for (Map map : list) {
                dbResultMap.put((String) map.get("wlapDate"), Integer.valueOf(map.get("wlapCount") + ""));
            }
        }

        // 遍历开始日期
        Date beginDate = Calendar.getInstance().getTime();
        Calendar beginCalendar = Calendar.getInstance();
        beginCalendar.setTime(beginDate);
        beginCalendar.add(Calendar.DATE, -30);
        // 遍历结束日期(不含当天)
        Date endDate = Calendar.getInstance().getTime();   // 遍历结日期
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(endDate);

        // 封装数据
        List<Object> dayList = new ArrayList<>();
        List<Object> countList = new ArrayList<>();

        while (true) {
            String tempStrDate = DateUtil.format(beginCalendar.getTime(), "yyyy-MM-dd");
            dayList.add(tempStrDate);
            if (dbResultMap.containsKey(tempStrDate)) {
                countList.add(dbResultMap.get(tempStrDate));
            } else {
                countList.add(0);
            }

            // 结束日期退出
            beginCalendar.add(Calendar.DATE, 1);
            if (DateUtil.format(beginCalendar.getTime(), "yyyy-MM-dd")
                    .equals(DateUtil.format(endCalendar.getTime(), "yyyy-MM-dd"))) {
                break;
            }

        }

        Map<String, List<Object>> resultMap = new HashMap<>();
        resultMap.put("dayList", dayList);
        resultMap.put("countList", countList);

        return resultMap;
    }
}
